package indicadores;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import solucao.SolucaoNumerica;
import br.org.mestrado.vais.util.PROBLEMA;

public class Run {

	static final String STORE_PATH = System.getProperty("user.home")
			+ "/VIS_many_obj/";

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		final File root = new File(STORE_PATH);

		// primeiro for, procura pelo problemas
		for (File problema : root.listFiles()) {

			final List<String> probs = new ArrayList<String>();

			// procura por objetivos
			for (File num_objetivos : problema.listFiles()) {

				if (num_objetivos.isDirectory()) {

					final int NUM_OBJECTIVES = Integer.parseInt(num_objetivos
							.getName());

					// controle de qual objetivo deve é minimização
					String[] control = new String[Integer
							.parseInt(num_objetivos.getName())];

					double[] max_vals = new double[Integer
							.parseInt(num_objetivos.getName())];

					Arrays.fill(control, "-");

					Arrays.fill(max_vals, -3);

					// lista probabilidades
					for (File probabilidades : num_objetivos.listFiles()) {

						if (probabilidades.isDirectory()) {

							if (!probs.contains(probabilidades.getName()))
								probs.add(probabilidades.getName());

							// hipervolume
							Indicador hipervolume = new Hipervolume(
									NUM_OBJECTIVES, probabilidades
											.getAbsolutePath(), "", max_vals);

							hipervolume.preencherObjetivosMaxMin(control);

							// spread
							Indicador spread = new Spread(NUM_OBJECTIVES,
									probabilidades.getAbsolutePath(), "");

							spread.preencherObjetivosMaxMin(control);

							// idg
							PROBLEMA dtlzx = PROBLEMA.valueOf(problema
									.getName());

							ArrayList<SolucaoNumerica> fronteira = dtlzx
									.obterFronteira(NUM_OBJECTIVES + 9,
											NUM_OBJECTIVES, 100);

							ArrayList<PontoFronteira> pftrue = new ArrayList<PontoFronteira>();

							for (Iterator<SolucaoNumerica> iterator = fronteira
									.iterator(); iterator.hasNext();) {

								SolucaoNumerica solucao = (SolucaoNumerica) iterator
										.next();

								PontoFronteira temp = new PontoFronteira(
										solucao.objetivos);

								pftrue.add(temp);
							}

							Indicador igd = new IGD(NUM_OBJECTIVES,
									probabilidades.getAbsolutePath(), "",
									pftrue);

							igd.preencherObjetivosMaxMin(control);

							try {
								hipervolume
										.calcularIndicadorArquivo(probabilidades
												.getAbsolutePath()
												+ "/run_objective.fit");

								spread.calcularIndicadorArquivo(probabilidades
										.getAbsolutePath()
										+ "/run_objective.fit");

								igd.calcularIndicadorArquivo(probabilidades
										.getAbsolutePath()
										+ "/run_objective.fit");

							} catch (IOException e) {
								System.err.println(e);
							}
						}
					}
				}

			}

			for (File num_objetivos : problema.listFiles()) {

				if (num_objetivos.isDirectory()) {
					// prepara arquivos
					Run run = new Run();

					try {
						run.preparArquivosIndicadores(STORE_PATH, problema
								.getName(), num_objetivos.getName(), probs
								.toArray(new String[0]), 30);
					} catch (IOException e) {
						System.err.println(e);
					}
				}
			}

		}

	}

	public void preparArquivosIndicadores(String dir, String problema,
			String objetivo, String[] algoritmos, int exec) throws IOException {

		Double[][] hyper = new Double[algoritmos.length][exec];
		Double[][] spread = new Double[algoritmos.length][exec];
		Double[][] gd = new Double[algoritmos.length][exec];

		BufferedReader h, s, g;

		for (int j = 0; j < algoritmos.length; j++) {

			String arqHyp = dir + problema + "/" + objetivo + "/"
					+ algoritmos[j] + "_hipervolume.txt";

			String arqSpread = dir + problema + "/" + objetivo + "/"
					+ algoritmos[j] + "_spread.txt";

			String arqGd = dir + problema + "/" + objetivo + "/"
					+ algoritmos[j] + "_igd.txt";

			System.out.println(arqHyp);
			System.out.println(arqSpread);
			System.out.println(arqGd);

			h = new BufferedReader(new FileReader(arqHyp));

			s = new BufferedReader(new FileReader(arqSpread));

			g = new BufferedReader(new FileReader(arqGd));

			int tam = 0;

			while (s.ready()) {

				Double hyp_val = new Double(h.readLine());

				Double spre_val = new Double(s.readLine());

				Double gd_val = new Double(g.readLine());

				hyper[j][tam] = hyp_val;

				spread[j][tam] = spre_val;

				gd[j][tam] = gd_val;

				tam++;
			}
		}

		PrintStream hypSaida = new PrintStream(dir + problema + "/" + problema
				+ "_hyper_" + objetivo + "_indicadores.txt");

		PrintStream spreSaida = new PrintStream(dir + problema + "/" + problema
				+ "_spread_" + objetivo + "_indicadores.txt");

		PrintStream gdSaida = new PrintStream(dir + problema + "/" + problema
				+ "_igd_" + objetivo + "_indicadores.txt");

		for (int j = 0; j < exec; j++) {
			for (int i = 0; i < algoritmos.length; i++) {
				try {
					hypSaida.print(hyper[i][j].toString().replace(".", ",")
							+ "\t");

					spreSaida.print(spread[i][j].toString().replace(".", ",")
							+ "\t");

					gdSaida.print(gd[i][j].toString().replace(".", ",") + "\t");

				} catch (NullPointerException ex) {
					ex.printStackTrace();
				}
			}

			hypSaida.println();

			spreSaida.println();

			gdSaida.println();
		}

	}

}
